﻿using System;
using System.Data;
using ltModel;

/// <summary>
/// ip
/// </summary>
public class IpHelper
{
    public static long GetIpNum(string ipAddress)
    {
        string[] ip = ipAddress.Split(new char[] { '.', ':' });
        long a = ParseIpPart(ip[0]);
        long b = ParseIpPart(ip[1]);
        long c = ParseIpPart(ip[2]);
        long d = 0;
        if (ip.Length == 4)
            d = ParseIpPart(ip[3]);

        return a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
    }
    private static long ParseIpPart(string part)
    {
        if (!Str.IsInt(part))
            return 0;
        return long.Parse(part);
    }

    /// <summary>
    /// 判断客户端的IP是否在某个ip段中  
    /// </summary>
    /// <param name="clientIp">客户端的IP</param>
    /// <param name="begin">开始IP</param>
    /// <param name="end">结束IP</param>
    /// <returns></returns>
    public static bool IsInner(long clientIp, long begin, long end)
    {
        return (clientIp >= begin) && (clientIp <= end);
    }

    private static bool IsIpPart(string part)
    {
        return Str.IsInt(part) || part == "*";
    }

    /// <summary>
    /// 是否为ip地址
    /// </summary>
    /// <param name="ip"></param>
    /// <returns></returns>
    public static bool IsIp(string ip)
    {
        string[] iplist = ip.Split(new char[] { '.', ':' });
        if (iplist != null && iplist.Length == 4)
        {
            if (IsIpPart(iplist[0]) &&
                IsIpPart(iplist[1]) &&
                IsIpPart(iplist[2]) &&
                IsIpPart(iplist[3]))
                return true;

        }
        return false;
    }

    private static long[] GetIpNums(string ip)
    {
        if (!ip.Contains("*"))
            return new long[] { GetIpNum(ip), 0 };
        long[] ipnums = new long[2];
        ipnums[0] = GetIpNum(ip.Replace("*", "0"));
        ipnums[1] = GetIpNum(ip.Replace("*", "255"));
        return ipnums;
    }

    /// <summary>
    /// ip地址是否允许访问
    /// </summary>
    /// <param name="ip"></param>
    /// <returns></returns>
    public static bool IsIpAllowed(string ip)
    {
        long ipNum = GetIpNum(ip);
        object o = SqlHelper.Instance.ExecuteScalar(string.Format("select count(*) from lt_iplist where (i_ipnum={0} or (i_ipnum<={0} and i_ipnum2>={0})) and i_type=0", ipNum));
        return Convert.ToInt32(o) > 0;
    }

    /// <summary>
    /// ip地址是否被锁定
    /// </summary>
    /// <param name="ip"></param>
    /// <returns></returns>
    public static bool IsIpLocked(string ip)
    {
        long ipNum = GetIpNum(ip);
        object o = SqlHelper.Instance.ExecuteScalar(string.Format("select count(*) from lt_iplist where (i_ipnum={0} or (i_ipnum<={0} and i_ipnum2>={0})) and i_type=1", ipNum));
        return Convert.ToInt32(o) > 0;
    }

    /// <summary>
    /// 添加ip 锁定
    /// </summary>
    /// <param name="ip"></param>
    public static void AddLocked(string ip)
    {
        Add(ip, 1);
    }

    /// <summary>
    /// 添加ip
    /// </summary>
    /// <param name="ip"></param>
    /// <param name="type"></param>
    public static void Add(string ip, byte type)
    {
        IDataParameter[] parms = GetParameters(ip, type, -1);
        SqlHelper.Instance.ExecuteNonQuery("Insert into lt_iplist(i_ip,i_ipnum,i_ipnum2,i_type) values(@i_ip,@i_ipnum,@i_ipnum2,@i_type)", parms);
    }

    /// <summary>
    /// 修改ip
    /// </summary>
    /// <param name="ip"></param>
    /// <param name="type"></param>
    /// <param name="id"></param>
    public static void Update(string ip, byte type, int id)
    {
        IDataParameter[] parms = GetParameters(ip, type, id);
        SqlHelper.Instance.ExecuteNonQuery("Update lt_iplist set i_ip=@i_ip,i_ipnum=@i_ipnum,i_ipnum2=@i_ipnum2,i_type=@i_type where i_id=@i_id", parms);
    }

    static IDataParameter[] GetParameters(string ip, byte type, int id)
    {
        long[] ipNums = GetIpNums(ip);
        IDataParameter[] parms = new IDataParameter[]{
            SqlParameterEx.CreateParameter("@i_ip", SqlDbType.VarChar,50, ip),
            SqlParameterEx.CreateParameter("@i_ipnum", SqlDbType.BigInt, ipNums[0]),
            SqlParameterEx.CreateParameter("@i_ipnum2", SqlDbType.BigInt, ipNums[1]),
            SqlParameterEx.CreateParameter("@i_type", SqlDbType.TinyInt, type),
            SqlParameterEx.CreateParameter("@i_id", SqlDbType.Int, id)
        };
        return parms;
    }
}